<!DOCTYPE html>
<!--[if IE 8]><html class="no-js lt-ie9" lang="en" > <![endif]-->
<!--[if gt IE 8]><!--> <html class="no-js" lang="en" > <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  
  
  
  <link rel="shortcut icon" href="../img/favicon.ico">
  <title>Ⅰ. JSON 与 .Net Core JSON - .NET JSON 源码分析</title>
  <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Lato:400,700|Roboto+Slab:400,700|Inconsolata:400,700" />

  <link rel="stylesheet" href="../css/theme.css" />
  <link rel="stylesheet" href="../css/theme_extra.css" />
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/styles/github.min.css" />
  
  <script>
    // Current page data
    var mkdocs_page_name = "\u2160. JSON \u4e0e .Net Core JSON";
    var mkdocs_page_input_path = "Introduction.md";
    var mkdocs_page_url = null;
  </script>
  
  <script src="../js/jquery-2.1.1.min.js" defer></script>
  <script src="../js/modernizr-2.8.3.min.js" defer></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/9.12.0/highlight.min.js"></script>
  <script>hljs.initHighlightingOnLoad();</script> 
  
</head>

<body class="wy-body-for-nav" role="document">

  <div class="wy-grid-for-nav">

    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side stickynav">
    <div class="wy-side-scroll">
      <div class="wy-side-nav-search">
        <a href=".." class="icon icon-home"> .NET JSON 源码分析</a>
        <div role="search">
  <form id ="rtd-search-form" class="wy-form" action="../search.html" method="get">
    <input type="text" name="q" placeholder="Search docs" title="Type search term here" />
  </form>
</div>
      </div>

      <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="..">首页</a>
                    </li>
                </ul>
                <ul class="current">
                    <li class="toctree-l1 current"><a class="reference internal current" href="./">Ⅰ. JSON 与 .Net Core JSON</a>
    <ul class="current">
    <li class="toctree-l2"><a class="reference internal" href="#json">什么是 JSON？</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#net-core-json">什么是 .NET Core JSON</a>
    </li>
    <li class="toctree-l2"><a class="reference internal" href="#net-core-json_1">怎么使用 .NET Core JSON</a>
    </li>
    </ul>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../Structure/">Ⅱ. .NET Core JSON 的结构</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../Procedure/">Ⅲ. 序列化与反序列化的过程</a>
                    </li>
                </ul>
                <ul>
                    <li class="toctree-l1"><a class="reference internal" href="../Summary/">Ⅳ. 总结</a>
                    </li>
                </ul>
      </div>
    </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" role="navigation" aria-label="top navigation">
        <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
        <a href="..">.NET JSON 源码分析</a>
      </nav>

      
      <div class="wy-nav-content">
        <div class="rst-content">
          <div role="navigation" aria-label="breadcrumbs navigation">
  <ul class="wy-breadcrumbs">
    <li><a href="..">Docs</a> &raquo;</li>
    
      
    
    <li>Ⅰ. JSON 与 .Net Core JSON</li>
    <li class="wy-breadcrumbs-aside">
      
    </li>
  </ul>
  
  <hr/>
</div>
          <div role="main">
            <div class="section">
              
                <h1 id="i-json-net-core-json">Ⅰ. JSON 与 .NET Core JSON</h1>
<h2 id="json">什么是 JSON？</h2>
<p>JSON 即 JavaScript Object Notation（JavaScript 对象表示法）是一种轻量级的数据交换语言，可用于对象的存储、传递、传输。</p>
<p>在 JSON 成为业界主流之前，XML 曾是互联网上传输结构化数据的标准格式，但 XML 存在着冗长、人类难以阅读等等一系列问题。在这一时期，很多编程语言也提供了一些用于将对象序列化、反序列化的 API，例如 Java 和 PHP 都提供了将对象转换为字节序列的机制，但这些机制通常只能在特定的编程语言中使用，不适合在不同的编程语言间传递对象。</p>
<p>JSON 最早出现于 2000 年左右，2005 年后成为主流。它是 JavaScript 的一个严格子集，利用了 JavaScript 的一些语法结构来表示对象，这一特点使得 JSON 非常适合。JSON 可读性很好、轻巧并且快速，并且被很多主流编程语言支持。</p>
<h2 id="net-core-json">什么是 .NET Core JSON</h2>
<p>在发布于 2019 年的 .NET Core 3.0 中，微软引入了一套新的原生 JSON 解析器 <code>System.Text.Json</code>，用于替代此前流行的 Json.NET。</p>
<blockquote>
<p>Json.NET 是 .NET 平台中一套成熟的开源 JSON 库，最早发布于 2007 年。
官方网站是：<a href="https://www.newtonsoft.com/json">https://www.newtonsoft.com/json</a></p>
</blockquote>
<p>既然 .NET 平台已经有了成熟的 JSON 库，微软开发新的 JSON 解析器自然是一种“造轮子”的行为。“造轮子”常常意味着重复的无用功，除非有某些理由不得不造轮子。微软确实在他们的<a href="https://devblogs.microsoft.com/dotnet/try-the-new-system-text-json-apis/">开发博客</a>和 <a href="https://github.com/dotnet/runtime/issues/27761">Github Issue</a> 中给出了这些理由，主要有下面两点：
* 提供更高性能的 JSON API；
* 解决 Json.NET 造成的 .NET 版本依赖问题。</p>
<p>在提供更高性能的 API 方面，微软主要有两个考虑。其一，.NET Core 2.1 中提供了一个新的 <code>Span&lt;T&gt;</code> 类，可以使得编解码 JSON 的内存效率有较大的提高，但 Json.NET 作为一个十余年的老开源项目，不适合搞支持 <code>Span&lt;T&gt;</code> 类这样的重大更改。其二，JSON 总是以 UTF-8 编码进行交换的，而 C# 的字符、字符串默认是 UTF-16 编码，如果在序列化和反序列化的时候直接支持 UTF-8 的输入输出，会有较大的性能提升。微软给出的测试结果显示，.NET Core JSON 的速度大约是 Json.NET 两倍左右。</p>
<p>关于依赖的问题相对好理解。Json.NET 毕竟是一个第三方库，它总是会依赖于某些特定的 .NET 版本。程序员如果要使用 JSON 解析，就必须使用 Json.NET 依赖的 .NET 版本。如果在 .NET 框架中提供原生的 JSON 解析支持，那么应用程序开发时就可以更自由地选用 .NET 框架版本。</p>
<blockquote>
<p>所谓“序列化”（serialization），即是将对象转化为可以存储或传输的字节序列的过程，有的场合也叫做“编码”（encode）；反序列化（deserialization）即是相反的过程，也叫做“解码”（decode）。</p>
</blockquote>
<h2 id="net-core-json_1">怎么使用 .NET Core JSON</h2>
<p>微软为 .NET 平台处理 JSON 提供了一份详尽的文档：<a href="https://docs.microsoft.com/zh-cn/dotnet/standard/serialization/system-text-json-overview">JSON 序列化概述</a>。</p>
<p>但我在这里还是需要提一下怎么用……后面的演示都将基于下面的这个类：</p>
<pre><code class="language-C#">public class WeatherForecast
{
    public DateTimeOffset Date { get; set; }
    public int TemperatureCelsius { get; set; }
    public string Summary { get; set; }
}
</code></pre>
<p>首先，使用 .NET Core 的 JSON 解析器需要引用 <code>System.Text.Json</code> 命名空间。如果需要定制序列化和反序列化的过程，则还需要引用 <code>System.Text.Json.Serialization</code> 命名空间。</p>
<pre><code class="language-C#">using System.Text.Json;
using System.Text.Json.Serialization;
</code></pre>
<p>序列化的方法很简单，只需要一行代码：</p>
<pre><code class="language-C#">string jsonString = JsonSerializer.Serialize(weatherForecast);
</code></pre>
<p>反序列化的方法也很简单，同样只需要一行代码：</p>
<pre><code class="language-C#">weatherForecast = JsonSerializer.Deserialize&lt;WeatherForecast&gt;(jsonString);
</code></pre>
<p>在文档中，除了这两种基本的方法，还提到了同步、异步等等各种不同的用法。</p>
<p>在前面我们提到过，.NET Core JSON 在设计之初就考虑到 JSON 使用 UTF-8 而 C# 字符串使用 UTF-16 的问题。因此，有必要了解序列化为 UTF-8 和从 UTF-8 进行反序列化的方法：</p>
<pre><code class="language-C#">// 序列化为 UTF-8
byte[] jsonUtf8Bytes;
jsonUtf8Bytes = JsonSerializer.SerializeToUtf8Bytes(weatherForecast);
// 从 UTF-8 进行反序列化
var readOnlySpan = new ReadOnlySpan&lt;byte&gt;(jsonUtf8Bytes);
weatherForecast = JsonSerializer.Deserialize&lt;WeatherForecast&gt;(readOnlySpan);
</code></pre>
<p>C# 和 Python 之类的编程语言不同，它的类的属性都是预先定义好的，因此在反序列化的时候需要指定生成的对象类型。</p>
              
            </div>
          </div>
          <footer>
  
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
      
        <a href="../Structure/" class="btn btn-neutral float-right" title="Ⅱ. .NET Core JSON 的结构">Next <span class="icon icon-circle-arrow-right"></span></a>
      
      
        <a href=".." class="btn btn-neutral" title="首页"><span class="icon icon-circle-arrow-left"></span> Previous</a>
      
    </div>
  

  <hr/>

  <div role="contentinfo">
    <!-- Copyright etc -->
    
  </div>

  Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>.
</footer>
      
        </div>
      </div>

    </section>

  </div>

  <div class="rst-versions" role="note" aria-label="versions">
    <span class="rst-current-version" data-toggle="rst-current-version">
      
      
        <span><a href=".." style="color: #fcfcfc;">&laquo; Previous</a></span>
      
      
        <span style="margin-left: 15px"><a href="../Structure/" style="color: #fcfcfc">Next &raquo;</a></span>
      
    </span>
</div>
    <script>var base_url = '..';</script>
    <script src="../js/theme.js" defer></script>
      <script src="../search/main.js" defer></script>
    <script defer>
        window.onload = function () {
            SphinxRtdTheme.Navigation.enable(true);
        };
    </script>

</body>
</html>
